import java.util.Random;
// 作业
public class ThreadDemo {
    private static Object locker1 = new Object();
    private static Object locker2 = new Object();
    private static Object locker3 = new Object();

    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    synchronized (locker1) {
                        locker1.wait();
                    }
                    System.out.print("A");
                    synchronized (locker2) {
                        locker2.notify();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread t2 = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    synchronized (locker2) {
                        locker2.wait();
                    }
                    System.out.print("B");
                    synchronized (locker3) {
                        locker3.notify();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread t3 = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    synchronized (locker3) {
                        locker3.wait();
                    }
                    System.out.println("C");
                    synchronized (locker1) {
                        locker1.notify();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t1.start();
        t2.start();
        t3.start();

        Thread.sleep(1000);

        // 唤醒 t1 线程
        synchronized (locker1) {
            locker1.notify();
        }
    }

    // 计数器
    private static volatile int COUNTER = 0;
    // 定义一个单独的锁对象
    private static Object lock = new Object();

    public static void main5(String[] args) {
        // 创建三个线程，并指定线程名，每个线程名分别用A,B,C表示
        Thread t1 = new Thread(() -> {
            // 循环10次
            for (int i = 0; i < 10; i++) {
                // 执行的代码加锁
                synchronized (lock) {
                    // 每次唤醒后都重新判断是否满足条件
                    // 每条线程判断的条件不一样，注意线程t1,t2
                    while (COUNTER % 3 != 0) {
                        try {
                            // 不满足输出条件时，主动等待并释放锁
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    // 满足输出条件，打印线程名，每条线程打印的内容不同
                    System.out.print(Thread.currentThread().getName());
                    // 累加计数
                    COUNTER++;
                    // 唤醒其他线程
                    lock.notifyAll();
                }
            }
        }, "A");

        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                synchronized (lock) {
                    while (COUNTER % 3 != 1) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.print(Thread.currentThread().getName());
                    COUNTER++;
                    lock.notifyAll();
                }
            }
        }, "B");

        Thread t3 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                synchronized (lock) {
                    while (COUNTER % 3 != 2) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                    // 换行打印
                    System.out.println(Thread.currentThread().getName());
                    COUNTER++;
                    lock.notifyAll();
                }
            }
        }, "C");

        // 启动线程
        t1.start();
        t2.start();
        t3.start();
    }

    public static void main4(String[] args) throws InterruptedException {
        char[] name = {'A','B','C'};
        // 同一个线程不能重复启动
        // 不符合题意
        for (int i = 0; i < 10; i++) {
            Thread[] threads = new Thread[3];
            for (int j = 0; j < 3; j++) {
                final int n = j;
                threads[j] = new Thread(() -> {
                    if (n != 0) {
                        try {
                            threads[n - 1].join();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.print(Thread.currentThread().getName());
                }, String.valueOf(name[j]));
            }
            for (Thread T : threads) {
                T.start();
            }
            threads[2].join();
            System.out.println();
        }
    }

    public static void main3(String[] args) {
        Thread[] threads = new Thread[3];
        char[] name = {'a','b','c'};
        for (int i = 0; i < 3; i++) {
            final int n = i;
            threads[i] = new Thread(() -> {
                try {
                    if (n != 2) {
                        threads[n + 1].join();
                    }
                    System.out.println(Thread.currentThread().getName());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, String.valueOf(name[i]));
        }
        for (Thread T : threads) {
            T.start();
        }
    }

    public static void main2(String[] args) throws InterruptedException {

        long startTime = System.currentTimeMillis();

        Random random = new Random();
        int[] array = new int[100000000];
        for (int i = 0; i < array.length; i++) {
            array[i] = random.nextInt(101);
        }

        long[] ret = {0, 0};

        Thread t1 = new Thread(() -> {
            for (int i = 0; i < array.length; i += 2) {
                ret[0] += array[i];
            }
        });
        Thread t2 = new Thread(() -> {
            for (int i = 1; i < array.length; i += 2) {
                ret[1] += array[i];
            }
        });

        t1.start();
        t2.start();

        t1.join();
        t2.join();

        long endTime = System.currentTimeMillis();

        System.out.println("奇数 = " + ret[1]);
        System.out.println("偶数 = " + ret[0]);
        System.out.println("总和 = " + (ret[0] + ret[1]));
        System.out.println("执行时长：" + (endTime - startTime) + "毫秒");
    }

    public static void main1(String[] args) throws InterruptedException {
        // 线程类型数组
        Thread[] threads = new Thread[20];

        // 循环创建线程对象
        for(int i=0; i<20; i++){
            final int n = i;
            threads[i] = new Thread(() -> {
                try {
                    // 等待上一个线程结束
                    if (n != 0) {
                        threads[n - 1].join();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(n);
            });
        }

        // 启动20个线程
        for(Thread t : threads){
            t.start();
        }

        threads[19].join();

        System.out.println("OK");
    }
}

